package com.up.interview.flowable.service;

import com.up.interview.flowable.entity.LeaveRequest;
import com.up.interview.flowable.repository.LeaveRequestRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: liuchengjun
 * @title: LeaveService
 * @projectName: 海联技术中台V2.0
 * @depart 软件事业部
 * @description:
 * @date: 2025/10/30/周四 16:11 (星期四)
 * @since V2.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class LeaveService {

    private final LeaveRequestRepository leaveRequestRepository;
    private final RuntimeService runtimeService;
    private final TaskService taskService;

    /**
     * 提交请假申请
     */
    @Transactional
    public LeaveRequest submitLeaveRequest(LeaveRequest leaveRequest) {
        // 1. 保存请假申请到数据库
        LeaveRequest saved = leaveRequestRepository.save(leaveRequest);
        log.info("保存请假申请: {}", saved);

        // 2. 准备流程变量
        Map<String, Object> variables = new HashMap<>();
        variables.put("employee", saved.getEmployee());
        variables.put("days", saved.getDays());
        variables.put("reason", saved.getReason());
        variables.put("leaveRequestId", saved.getId());

        // 3. 启动流程实例 (leave-process 是流程定义的 key)
        String processInstanceId = runtimeService
                .startProcessInstanceByKey("leave-process", variables)
                .getId();

        //完成用户任务
        // 4. 【关键】查询并完成 submitLeave 任务
        Task task = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .taskDefinitionKey("submitLeave")
                .singleResult();

        if (task != null) {
            taskService.complete(task.getId());
            log.info("完成提交请假任务: {}", task.getId());
        }


        log.info("启动流程实例: {}", processInstanceId);

        // 4. 更新请假申请的流程实例ID
        saved.setProcessInstanceId(processInstanceId);
        leaveRequestRepository.save(saved);

        return saved;
    }

    /**
     * 获取待办任务列表
     */
    public List<Task> getTasks(String assignee) {
        return taskService.createTaskQuery()
                .taskAssignee(assignee)
                .list();
    }

    /**
     * 审批请假申请
     */
    @Transactional
    public void approveLeave(String taskId, boolean approved, String comment) {
        // 1. 获取任务信息
        Task task = taskService.createTaskQuery()
                .taskId(taskId)
                .singleResult();

        if (task == null) {
            throw new RuntimeException("任务不存在: " + taskId);
        }

        // 2. 获取流程变量
        String processInstanceId = task.getProcessInstanceId();
        Long leaveRequestId = (Long) runtimeService.getVariable(processInstanceId, "leaveRequestId");

        // 3. 更新请假申请状态
        LeaveRequest leaveRequest = leaveRequestRepository.findById(leaveRequestId)
                .orElseThrow(() -> new RuntimeException("请假申请不存在"));

        leaveRequest.setStatus(approved ? "APPROVED" : "REJECTED");
        leaveRequest.setApprovalComment(comment);
        leaveRequestRepository.save(leaveRequest);

        // 4. 完成任务,传递审批结果
        Map<String, Object> variables = new HashMap<>();
        variables.put("approved", approved);
        variables.put("comment", comment);

        taskService.complete(taskId, variables);
        log.info("完成任务: {}, 审批结果: {}", taskId, approved ? "通过" : "拒绝");
    }

    /**
     * 查询所有请假申请
     */
    public List<LeaveRequest> getAllLeaveRequests() {
        return leaveRequestRepository.findAll();
    }

    /**
     * 根据员工查询请假申请
     */
    public List<LeaveRequest> getLeaveRequestsByEmployee(String employee) {
        return leaveRequestRepository.findByEmployee(employee);
    }
}
